﻿using System;

namespace H.Win32.Memory
{
    /// <summary>
    /// 指针
    /// </summary>
    public sealed class Pointer
    {
        internal string _moduleName;

        internal int _moduleOffset;

        internal IntPtr _baseAddr;

        internal int[] _offset;

        internal PointerType _type;

        internal IntPtr _lastAddr;

        /// <summary>
        /// 模块名
        /// </summary>
        public string ModuleName
        {
            get
            {
                if (this._type != PointerType.ModuleName_Offset)
                {
                    throw new NotSupportedException("使用了地址+偏移，未使用模块名");
                }
                return this._moduleName;
            }
        }

        /// <summary>
        /// 模块偏移
        /// </summary>
        public int ModuleOffset
        {
            get
            {
                if (this._type != PointerType.ModuleName_Offset)
                {
                    throw new NotSupportedException("使用了地址+偏移，未使用模块偏移");
                }
                return this._moduleOffset;
            }
        }

        /// <summary>
        /// 基础地址
        /// </summary>
        public IntPtr BaseAddr
        {
            get
            {
                if (this._type != PointerType.Address_Offset)
                {
                    throw new NotSupportedException("使用了模块偏移，未使用地址+偏移");
                }
                return this._baseAddr;
            }
        }

        /// <summary>
        /// 偏移
        /// </summary>
        public int[] Offset => this._offset;

        /// <summary>
        /// 实例化指针结构
        /// </summary>
        /// <param name="moduleName">模块名</param>
        /// <param name="moduleOffset">模块偏移</param>
        /// <param name="offset">偏移</param>
        public Pointer(string moduleName, int moduleOffset, params int[] offset)
        {
            if (string.IsNullOrEmpty(moduleName))
            {
                throw new ArgumentOutOfRangeException();
            }

            _moduleName = moduleName;
            _moduleOffset = moduleOffset;
            _offset = offset;
            _type = PointerType.ModuleName_Offset;
        }

        /// <summary>
        /// 实例化指针结构
        /// </summary>
        /// <param name="baseAddr">基础地址</param>
        /// <param name="offset">偏移</param>
        public Pointer(IntPtr baseAddr, params int[] offset)
        {
            _baseAddr = baseAddr;
            _offset = offset;
            _type = PointerType.Address_Offset;
        }
    }
}
